package cn.xny.txcc.service.impl;

import cn.xny.txcc.domain.MessageSms;
import cn.xny.txcc.domain.User;
import cn.xny.txcc.dto.PhoneCodeDto;
import cn.xny.txcc.exception.BusinessException;
import cn.xny.txcc.feignclients.UserFeignClient;
import cn.xny.txcc.mapper.MessageSmsMapper;
import cn.xny.txcc.service.CommonCodeService;
import cn.xny.txcc.util.StrUtils;
import cn.xny.txcc.util.VerifyCodeUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
public class CommonCodeServiceImpl implements CommonCodeService {

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    @Autowired
    private UserFeignClient userFeignClient;
    @Autowired
    private MessageSmsMapper messageSmsMapper;

    @Override
    public String getImageCode(String imageCodeKey) {
        //获取随机验证码
        String code = StrUtils.getComplexRandomString(4);
        //保存到Redis中
        redisTemplate.opsForValue().set(imageCodeKey,code,5, TimeUnit.MINUTES);
        //将验证码放到图片中去
        return  VerifyCodeUtils.verifyCode(115,40,code);



    }

    @Override
    public void getPhoneCode(PhoneCodeDto phoneCodeDto) {
         //校验
        //1.校验空值
        if(StringUtils.isEmpty(phoneCodeDto.getImageCode()) ||  StringUtils.isEmpty(phoneCodeDto.getMobile())){
            throw new BusinessException("信息不能为空");
        }
        //2.校验手机号是否被注册过
        User user = userFeignClient.getUser(phoneCodeDto.getMobile());
        if (user != null){
            throw new BusinessException("当前手机号码已被注册，请直接登录");
        }
        //3.校验手机验证码是否过期
        Object obj = redisTemplate.opsForValue().get(phoneCodeDto.getImageCodeKey());
        if(obj == null){
            throw new BusinessException("图形验证码已过期");
        }
        //如果输入的验证码和Redis中不同
        if (!phoneCodeDto.getImageCode().equalsIgnoreCase(obj.toString())){
            throw new BusinessException("图形验证码错误");



        }
        //判断拉黑
        blankList(phoneCodeDto);
        //二.获取手机短信验证码
        //1.通过key从Redis获取手机短信验证码
        Object MobileCodeObj = redisTemplate.opsForValue().get("register:" + phoneCodeDto.getMobile());
        //2.判断是否为null
        String MobileCode = null;
        if (MobileCodeObj==null){
            //为空手机验证码过期了--重新生成一个
            MobileCode = StrUtils.getRandomString(4);
        }else {
            //不为空说明手机验证码没有过期,然后判断是否过了重发时间
            long now = System.currentTimeMillis();
            long odl = Long.parseLong(MobileCodeObj.toString().split(":")[1]);
           if((now - odl)<1*60*1000){
               //没有过重发时间，违规操作
               throw new BusinessException("请勿重新发送验证码");

           }else {
               //过来重发时间，重新发送验证码
               MobileCode = MobileCodeObj.toString().split(":")[0];
           }

        }
        //刷新过期时间=重新添加一次数据到Redis
        redisTemplate.opsForValue().set("register:"+phoneCodeDto.getMobile()
           ,MobileCode+":"+System.currentTimeMillis(),10,TimeUnit.MINUTES);
        //调用中国网建接口发送短信
        System.out.println("你的验证码是："+MobileCode+"请在十分钟内使用");






        //将验证的信息保存到MessageSms数据库中
        MessageSms messageSms = new MessageSms();

        messageSms.setTitle("注册验证码");
        messageSms.setContent("你的验证码是："+MobileCode+"请在十分钟内使用");
        messageSms.setSendTime(new Date());
        messageSms.setPhone(phoneCodeDto.getMobile());
        //获取当前的请求
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        //获取ip地址
        String ip = requestAttributes.getRequest().getRemoteAddr();
        //设置ip地址
        messageSms.setIp(ip);
       //添加到数据库
        messageSmsMapper.insert(messageSms);



    }

    public void blankList(PhoneCodeDto phoneCodeDto){

        String mobile = phoneCodeDto.getMobile();
        //判断Redis中是否有手机号
        if(redisTemplate.opsForValue().get("blackList"+mobile)==null){
            //没有就设置值并存储30分钟
            redisTemplate.opsForValue().set("blackList"+mobile,mobile,30,TimeUnit.MINUTES);
            //设置并记录次数
            redisTemplate.opsForValue().set(mobile,0,30,TimeUnit.MINUTES);
        }
        //判断手机号是否与Redis中相同
        if(mobile.equals(redisTemplate.opsForValue().get("blackList"+mobile))){
            //获取存放在Redis记录次数的
            Object obj = redisTemplate.opsForValue().get(mobile);
             //转换成int类型并记录次数
            int i = Integer.parseInt(obj.toString());
            i=i+1;
            redisTemplate.opsForValue().set(mobile,i,30,TimeUnit.MINUTES);
            //当i大于2时就给这个号码拉黑，禁用
            if(i>2){
                //禁用2分钟
                redisTemplate.opsForValue().set("blackList"+mobile,mobile,2,TimeUnit.MINUTES);

                throw new BusinessException("该号码涉嫌违规操作，请稍后重试");
            }

        }


    }

}
